/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.fd.manager;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.xy.biz.fd.domain.bo.DocumentBO;
import com.xy.biz.fd.domain.po.DocumentPO;
import com.xy.biz.fd.domain.query.DocumentQuery;
import com.xy.biz.fd.domain.resp.GetDocumentResponse;

/**
 *
 *
 * @author wwj
 * @date 2021-2-1
 */
public interface DocumentManager {

	/**
	 * 保存
	 *
	 * @param documentBO
	 */
	GetDocumentResponse saveDocument(DocumentBO documentBO);

	/**
	 * 保存多个
	 *
	 * @param collection
	 */
	List<GetDocumentResponse> saveAllDocument(Collection<DocumentBO> collection);

	/**
	 * 更新
	 *
	 * @param documentBO
	 */
	int updateDocument(DocumentBO documentBO);

	/**
	 * 批量更新
	 *
	 * @param documentBOS
	 */
	int updateDocumentAll(Collection<DocumentBO> documentBOS);

	/**
	 * 根据Id批量更新
	 *
	 * @param query
	 */
	int updateDocumentByIds(DocumentQuery query);

	/**
	 * 更新权限
	 *
	 * @param documentBO
	 */
	int updateDocumentPermission(DocumentBO documentBO);

	/**
	 * 删除
	 *
	 * @param documentId
	 */
	int deleteDocument(Long documentId);

	/**
	 * 删除
	 *
	 * @param documentIds
	 */
	int deleteDocuments(Collection<Long> documentIds);

	/**
	 * 根据路径查找
	 *
	 * @param path
	 * @return
	 */
	DocumentBO getDocumentPath(String path);

	/**
	 * 查找一个
	 *
	 * @param documentId
	 * @return
	 */
	DocumentBO getDocument(Long documentId);

	/**
	 * 查找一个流程最新版本x
	 *
	 * @param documentQuery
	 * @return
	 */
	DocumentBO getLatestVersion(DocumentQuery documentQuery);

	/**
	 * 查找多个
	 *
	 * @param collection 标识集合
	 */
	List<DocumentBO> listDocumentById(Collection<Long> collection);

	/**
	 * 查找多个
	 *
	 * @param query 查找条件
	 */
	List<DocumentBO> listDocument(DocumentQuery query);

	/**
	 * 统计个数
	 *
	 * @param query 查找条件
	 */
	int countDocument(DocumentQuery query);

	/**
	 * 根据文件名模糊查找
	 *
	 * @param documentBO 文件BO
	 * @return document集合
	 */
	List<DocumentBO> listDocumentByName(DocumentBO documentBO);


	default <T> void buildByDocument(Collection<T> source,
									 Collection<Long> documentIdCollection,
									 Function<T, Long> documentIdGetter,
									 BiConsumer<T, DocumentBO> builder) {
		Objects.requireNonNull(documentIdGetter, "The documentIdGetter is required.");
		Objects.requireNonNull(builder, "The builder is required.");
		if(source == null || source.size() == 0) {
			return;
		}
		if(documentIdCollection == null || documentIdCollection.size() == 0) {
			return;
		}
		Set<Long> documentIdSet = new HashSet<>(documentIdCollection);
		List<DocumentBO> documentBOList = listDocumentById(documentIdSet);
		if(documentBOList != null && documentBOList.size() > 0) {
			Map<Long, DocumentBO> documentBOMap = documentBOList.stream().collect(Collectors.toMap(DocumentBO::getDocumentId, e -> e));
			DocumentBO documentBO;
			Long documentId;
			for(T entity : source) {
				documentId = documentIdGetter.apply(entity);
				documentBO = documentBOMap.get(documentId);
				if(documentBO != null) {
					builder.accept(entity, documentBO);
				}
			}
		}
	}

	/**
	 * 根据path跟新size
	 * @param build
	 * @return
	 */
    DocumentPO updateDocumentSizeByPath(DocumentBO build);
}
